from sqlalchemy.orm import Session
from core.response import resp_500
from core.logger import logger

from app.monitor_metrics.models.prom_alarm_metrics import PromAlarmMetrics
from app.monitor_metrics.handlers.prom_alarm_set_handler import PromAlarmSetHandler
from app.monitor_metrics.models.prom_alarm_set import PromAlarmSet

class PromAlarmMetricsHandler():
    """  PromAlarmMetrics Handler
    """
    def __init__(self):
        self.prom_alarm_set_handler = PromAlarmSetHandler()


    def get_alarm_metrics_search(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        根据表字段模糊匹配，获取告警指标信息
        """
        try:
            field_info = {field: value}
            order_info = {"classes": "asc", "name": "asc"}
            result = PromAlarmMetrics.filter_by_field_search(db, page, per_page, field_info, order_info)
            if not result:
                logger.error(f"get alarm metrics search, result is null => {field}:{value}")
                return False, None

        except Exception as e:
            message = f"get alarm metrics search by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result



    def get_alarm_metrics_match(self, db: Session, page: int, per_page: int, field: str, value: str):
        """
        根据表字段完全匹配，获取告警指标信息
        """
        try:
            result = PromAlarmMetrics.filter_by_field_match(db, page, per_page, {field: value})
            if not result:
                logger.error(f"get alarm metrics match, result is null => {field}:{value}")
                return False

        except Exception as e:
            message = f"get alarm metrics match by {field}:{value} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return result


    def get_alarm_metrics_classes(self, db: Session, page: int, per_page: int, classes: str, type: str):
        """
        根据表字段完全匹配，获取告警指标信息
        """
        try:
            result = PromAlarmMetrics.filter_by_field_match(db, page, per_page, {"classes": classes, "type": type})
            if not result:
                logger.error(f"get alarm metrics classes, result is null => classes:{classes} type:{type}")
                return False, None

        except Exception as e:
            message = f"get alarm metrics classes by classes:{classes} type:{type} error"
            logger.exception(f"{message} => {e}")
            return resp_500(message)

        return True, result

    def add_alarm_metrics(self, db: Session, data: dict):
        """
        创建告警指标
        """
        try:
            alarm_metrics_object = PromAlarmMetrics.get_object_by_name(db, data["name"])
            if alarm_metrics_object:
                # 如果存在， 则异常返回
                logger.error(f"add alarm metrics failed, name:{data['name']} was exist")
                return False

            result = PromAlarmMetrics.add(db, data)
            if not result:
                logger.error(f"add alarm metrics to database failed")
                return False
        except Exception as e:
            message = f"add alarm metrics error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def update_alarm_metrics(self, db: Session, data: dict):
        """
        修改告警指标信息
        """
        try:
            alarm_metrics_object = PromAlarmMetrics.get_object_by_uuid(db, data['uuid'])
            if not alarm_metrics_object:
                # 如果不存在， 则异常返回
                logger.error(f"update alarm metrics failed, uuid:{data['uuid']} not exist")
                return False

            # 更新告警指标
            alarm_metrics_info = PromAlarmMetrics.get_object_info_by_uuid(db, data['uuid'])
            result = PromAlarmMetrics.update(db, data)
            if not result:
                logger.error(f"update alarm metrics to database failed")
                return False

            # 更新prometheus引用此指标的所有规则
            alarm_sets_info = PromAlarmSet.get_object_info_by_alarm_metrics(db, data['uuid'])
            for alarm_set_info in alarm_sets_info:
                result = self.prom_alarm_set_handler.alarm_set_sync_prometheus_rule(db, alarm_set_info["uuid"])
                if not result:
                    # 更新失败，回滚数据
                    PromAlarmMetrics.update(db, alarm_metrics_info)
                    logger.error(f"update_alarm_metrics: update alarm_set=>{alarm_set_info['name']}:{alarm_set_info['uuid']} failed")
                    return False
        except Exception as e:
            message = f"update alarm metrics error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True



    def delete_alarm_metrics(self, db: Session, data: dict):
        """
        删除告警指标信息
        """
        try:
            alarm_metrics_object = PromAlarmMetrics.get_object_by_uuid(db, data['uuid'])
            if not alarm_metrics_object:
                # 如果不存在， 则异常返回
                logger.error(f"delete alarm metrics failed, uuid:{data['uuid']} not exist")
                return False

            alarm_sets_info = PromAlarmSet.get_object_info_by_alarm_metrics(db, data['uuid'])
            if len(alarm_sets_info) != 0:
                # 如果有告警规则引用， 则异常返回
                logger.error(f"delete alarm metrics failed, uuid:{data['uuid']} not exist")
                return False

            # 删除告警指标
            PromAlarmMetrics.delete_object_by_uuid(db, data['uuid'])
        except Exception as e:
            message = f"delete alarm metrics error"
            logger.exception(f"{message} data:{data} => {e}")
            return resp_500(message)

        return True




